package me.buick.util.jmeter.snmpprocessvisualizers;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

import org.apache.jmeter.samplers.Clearable;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.visualizers.GraphListener;
import org.apache.jmeter.visualizers.ImageVisualizer;
import org.apache.jmeter.visualizers.MonitorTabPane;
import org.apache.jmeter.visualizers.Sample;
import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

public class MonitorSNMPProcessVisualizer  extends AbstractVisualizer implements ImageVisualizer, ItemListener,
		GraphListener, Clearable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -282213507955749239L;

	private MonitorTabPane TABPANE;

	private SNMPProcessMonitorCPUPanel 		   CPUPANE;
	private SNMPProcessMonitorMEMPanel 		   MEMPANE;
	private SNMPProcessMonitorDetailPanel	   DETPANE;

	private SNMPProcessMonitorSNMPAccumModel MODEL;

	private SNMPProcessMonitorSNMPGraph GRAPH;

	public static final String BUFFER = "monitor.buffer.size"; // $NON-NLS-1$

	private static final Logger log = LoggingManager.getLoggerForClass();

	/**
	 * Constructor for the GraphVisualizer object.
	 */
	public MonitorSNMPProcessVisualizer() {
		this.isStats = true;
		initModel();
		init();
	}

	private void initModel() {
		MODEL = new SNMPProcessMonitorSNMPAccumModel(this.getName());
		GRAPH = new SNMPProcessMonitorSNMPGraph(MODEL);
		MODEL.setBufferSize(JMeterUtils.getPropDefault(BUFFER, 800));
	}
	
	public String getStaticLabel() {
		return "SNMP Process Monitor"; // $NON-NLS-1$
	}

	public String getLabelResource() {
		return null; // $NON-NLS-1$
	}

	public void add(SampleResult res) {
		MODEL.addSample(res);
		MODEL.setSNMPSuiteID(this.getName());
		try {
			collector.recordStats(this.MODEL.getLastSample().cloneMonitorStats());
		} catch (Exception e) {
			// for now just swallow the exception
			log.debug("StatsModel was null", e);
		}
	}

	public Image getImage() {
		Image result = GRAPH.createImage(this.getWidth(), this.getHeight());
		Graphics image = result.getGraphics();
		GRAPH.paintComponent(image);
		return result;
	}

	public void itemStateChanged(ItemEvent e) {
	}

	public synchronized void updateGui() {
		this.repaint();
	}

	public synchronized void updateGui(Sample s) {
		this.repaint();
	}

	/**
	 * Initialize the GUI.
	 */
	private void init() {
		this.setLayout(new BorderLayout());

		// MAIN PANEL
		Border margin = new EmptyBorder(10, 10, 5, 10);
		this.setBorder(margin);

		// Add the main panel and the graph
		this.add(this.makeTitlePanel(), BorderLayout.NORTH);
		this.createTabs();
	}

	private void createTabs() {
		TABPANE = new MonitorTabPane();
		createCPUPane(TABPANE);
		createMEMPane(TABPANE);
		createDETPane(TABPANE);
		this.add(TABPANE, BorderLayout.CENTER);
	}
	
	private void createCPUPane(MonitorTabPane pane) {
		CPUPANE = new SNMPProcessMonitorCPUPanel(MODEL); 
		pane.addTab("CPU Usage Overview", CPUPANE); // $NON-NLS-1$
	}
	
	private void createMEMPane(MonitorTabPane pane) {
		MEMPANE = new SNMPProcessMonitorMEMPanel(MODEL); 
		pane.addTab("Memory Usage Overview", MEMPANE); // $NON-NLS-1$
	}
	
	private void createDETPane(MonitorTabPane pane) {
		DETPANE = new SNMPProcessMonitorDetailPanel(MODEL);
		pane.add("Process Detail", DETPANE);
	}

	/**
	 * Clears the MonitorAccumModel.
	 */
	public void clearData() {
		this.MODEL.clearData();
		this.CPUPANE.clearData();
		this.MEMPANE.clearData();
		this.DETPANE.clearData();
	}
}
